#pragma once

#include <cstdint>
#include <type_traits>
#include <memory>
#include <string>

#ifdef _WIN32
#define FILEPATH_SEPARATOR '\\'
#else // Unix style 
#define FILEPATH_SEPARATOR '/'
#endif // _WIN32


namespace os_helper {
	
	bool is_intel_byte_ordering();
#if 0
	uint16_t intel_to_motorola(uint16_t num);
	uint32_t intel_to_motorola(uint32_t num);
	uint64_t intel_to_motorola(uint64_t num);
#endif
	uint16_t motorola_to_intel(uint16_t num);
	uint32_t motorola_to_intel(uint32_t num);
	uint64_t motorola_to_intel(uint64_t num);

	std::string file_suffix(const std::string& filepath);

	std::string simple_filename(const std::string& filepath);

	/// get the i-th byte of integer num, which consist of 1...8byte
	/// e.g. T = uint32_t, num = 0x12345678
	/// for intel byte ordering system:
	/// 4 bytes of num order by ascending address: 0x78, 0x56, 0x34, 0x12
	template<class T>
	uint8_t& byte_of_number(T num, int i)
	{
		uint8_t* head = (uint8_t*)&num;
		uint8_t* p;

		if (is_intel_byte_ordering()) {
			p = head + i;
		}
		else {
			p = head + sizeof(T) - 1 - i;
		}
		return *p;
	}
	template<class T>
	T set_byte(T num, int n)
	{
		auto& b = byte_of_number(num, n);
		b = 0xFF;
		return num;
	}
	template<class T>
	T clear_byte(T num, int n)
	{
		auto& b = byte_of_number(num, n);
		b = 0x00;
		return num;
	}
}

